﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WF.VecDraw.Dialog
{
	/// <summary>
	/// Interaction logic for ColorDialog.xaml
	/// </summary>
	public partial class ColorDialog : Window
	{
		Color _selectedColor = Colors.Transparent;
		double colorAlpha = 255;

		public ColorDialog()
		{
			InitializeComponent();
		}

		bool _colorLock = false;
		public Color SelectedColor
		{
			get 
            { 
                return _selectedColor;
            }
			set
			{
				if (_selectedColor != value)
				{
					if (!_colorLock)
					{
						_selectedColor = value;

						_colorLock = true;
						UpdateInk();
						CreateAlphaLinearBrush();

						SetARGBSliderPosition();
						_colorLock = false;
					}
				}
			}
		}

		double Alpha
		{
			get
			{
				return colorAlpha;
			}
			set
			{
				if (value > 255)
					colorAlpha = 255;
				else if (value < 0)
					colorAlpha = 0;
				else
					colorAlpha = value;
			}
		}

		private void UpdateInk()
		{
			selectedColorDisplay.Fill = new SolidColorBrush(SelectedColor);
		}

        private void CreateAlphaLinearBrush()
        {
            //if (SelectedColor != Colors.Transparent)
            //{
            Color startColor = Color.FromArgb(
                    (byte)0,
                    SelectedColor.R,
                    SelectedColor.G,
                    SelectedColor.B);

            Color endColor = Color.FromArgb(
                    (byte)255,
                    SelectedColor.R,
                    SelectedColor.G,
                    SelectedColor.B);

            LinearGradientBrush alphaBrush =
                new LinearGradientBrush(startColor, endColor,
                    new Point(0, 0), new Point(1, 0));

            if (AlphaBorder != null)
            {
                //AlphaSlider.IsEnabled = true;
                AlphaBorder.Background = alphaBrush;
            }
            //}
            //else
            //{
            //    if (AlphaBorder != null)
            //    {
            //        AlphaBorder.Background = Brushes.Transparent;
            //        //AlphaSlider.IsEnabled = false;
            //    }
            //}

        }

		private void SetARGBSliderPosition()
		{
			if (rColorSlider != null &&
				gColorSlider != null &&
				bColorSlider != null &&
				AlphaSlider != null)
			{
				if (SelectedColor != Colors.Transparent)
				{
					AlphaSlider.IsEnabled = true;
					rColorSlider.IsEnabled = true;
					gColorSlider.IsEnabled = true;
					bColorSlider.IsEnabled = true;

					rColorSlider.Value = SelectedColor.R;
					gColorSlider.Value = SelectedColor.G;
					bColorSlider.Value = SelectedColor.B;
					AlphaSlider.Value = SelectedColor.A;

					txtColorA.Text = SelectedColor.A.ToString();
					txtColorR.Text = SelectedColor.R.ToString();
					txtColorG.Text = SelectedColor.G.ToString();
					txtColorB.Text = SelectedColor.B.ToString();
				}
				else
				{
					AlphaSlider.IsEnabled = false;
					rColorSlider.IsEnabled = false;
					gColorSlider.IsEnabled = false;
					bColorSlider.IsEnabled = false;

					rColorSlider.Value = SelectedColor.R;
					gColorSlider.Value = SelectedColor.G;
					bColorSlider.Value = SelectedColor.B;
					AlphaSlider.Value = SelectedColor.A;
				}
			}
		}

		private void Window_Loaded(object sender, RoutedEventArgs e)
		{
			Color startColor = Color.FromArgb(
					(byte)255,
					0,
					0,
					0);

			Color endColor = Color.FromArgb(
					(byte)255,
					255,
					0,
					0);

			if (rBorder != null)
			{
				rBorder.Background = new LinearGradientBrush(startColor, endColor,
						new Point(0, 0), new Point(1, 0));
				rColorSlider.Value = SelectedColor.R;
			}

			endColor = Color.FromArgb(
					(byte)255,
					0,
					255,
					0);

			if (gBorder != null)
			{
				gBorder.Background = new LinearGradientBrush(startColor, endColor,
						new Point(0, 0), new Point(1, 0));
				gColorSlider.Value = SelectedColor.G;
			}

			endColor = Color.FromArgb(
					(byte)255,
					0,
					0,
					255);

			if (bBorder != null)
			{
				bBorder.Background = new LinearGradientBrush(startColor, endColor,
						new Point(0, 0), new Point(1, 0));
				bColorSlider.Value = SelectedColor.B;
			}
		}

		private void ColorPalete_MouseUp(object sender, MouseButtonEventArgs e)
		{
			try
			{
				CroppedBitmap cb = new CroppedBitmap(ColorImage.Source as BitmapSource,
					new Int32Rect((int)Mouse.GetPosition(ColorPalete).X,
						(int)Mouse.GetPosition(ColorPalete).Y, 1, 1));

				byte[] pixels = new byte[4];

                try
                {
                    cb.CopyPixels(pixels, 4, 0);
                }
                catch { }

				//Ok now, so update the mouse cursor position and the SelectedColor
				ellipsePixel.SetValue(Canvas.LeftProperty, (double)(Mouse.GetPosition(ColorPalete).X - 2.5));
				ellipsePixel.SetValue(Canvas.TopProperty, (double)(Mouse.GetPosition(ColorPalete).Y - 2.5));
				ColorPalete.InvalidateVisual();

                //if previos color is transparent than the slider has to be reset else the color will not be seen
                if (_selectedColor == Colors.Transparent && AlphaSlider.Value == 0)
                    AlphaSlider.Value = 255;

				SelectedColor = Color.FromArgb((byte)Alpha, pixels[2], pixels[1], pixels[0]);
			}
			catch
			{
				//not much we can do
			}
		}

		private void btnOK_Click(object sender, RoutedEventArgs e)
		{
			DialogResult = true;
			this.Close();
		}

		private void AlphaSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			Alpha = AlphaSlider.Value;
			SelectedColor =
			   Color.FromArgb(
				   (byte)Alpha,
				   SelectedColor.R,
				   SelectedColor.G,
				   SelectedColor.B);

			if (txtColorA != null)
				txtColorA.Text = SelectedColor.A.ToString();
		}

		private void ColorSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			if (rColorSlider != null &&
				gColorSlider != null &&
				bColorSlider != null)
			{
				SelectedColor =
					Color.FromArgb(
					(byte)Alpha,
					   (byte)rColorSlider.Value,
					   SelectedColor.G,
					   SelectedColor.B);

				//txtColorA.Text = SelectedColor.A.ToString();
				txtColorR.Text = SelectedColor.R.ToString();
				txtColorG.Text = SelectedColor.G.ToString();
				txtColorB.Text = SelectedColor.B.ToString();
			}
		}

		private void rColorSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			if (rColorSlider != null)
			{
				SelectedColor =
					Color.FromArgb(
					(byte)Alpha,
					   (byte)rColorSlider.Value,
					   SelectedColor.G,
					   SelectedColor.B);

				if (txtColorR != null)
					txtColorR.Text = SelectedColor.R.ToString();
			}
		}

		private void gColorSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			if (gColorSlider != null)
			{
				SelectedColor =
					Color.FromArgb(
					(byte)Alpha,
					   SelectedColor.R,
					   (byte)gColorSlider.Value,
					   SelectedColor.B);

				if (txtColorG != null)
					txtColorG.Text = SelectedColor.G.ToString();
			}
		}

		private void bColorSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			if (bColorSlider != null)
			{
				SelectedColor =
					Color.FromArgb(
					(byte)Alpha,
					   SelectedColor.R,
					   SelectedColor.G,
					   (byte)bColorSlider.Value);

				if (txtColorB != null)
					txtColorB.Text = SelectedColor.B.ToString();
			}
		}

		private void txtColor_TextChanged(object sender, TextChangedEventArgs e)
		{
			string text = ((TextBox)sender).Text;

			try
			{
				if (sender == txtColorA)
					AlphaSlider.Value = int.Parse(text);
				else if (sender == txtColorR)
					rColorSlider.Value = int.Parse(text);
				else if (sender == txtColorB)
					bColorSlider.Value = int.Parse(text);
				else if (sender == txtColorG)
					gColorSlider.Value = int.Parse(text);
			}
			catch { }

			if (sender == txtColorA && text != AlphaSlider.Value.ToString())
				((TextBox)sender).Text = AlphaSlider.Value.ToString();
			else if (sender == txtColorR && text != rColorSlider.Value.ToString())
				((TextBox)sender).Text = rColorSlider.Value.ToString();
			else if (sender == txtColorB && text != bColorSlider.Value.ToString())
				((TextBox)sender).Text = bColorSlider.Value.ToString();
			else if (sender == txtColorG && text != gColorSlider.Value.ToString())
				((TextBox)sender).Text = gColorSlider.Value.ToString();
		}

		private void Window_KeyUp(object sender, KeyEventArgs e)
		{
			if (e.Key == Key.Escape)
			{
				DialogResult = false;
				this.Close();
			}
		}

		private void ColorRect_MouseEnter(object sender, MouseEventArgs e)
		{
			((Rectangle)sender).Stroke = Brushes.White;
			((Rectangle)sender).StrokeThickness = 1;
		}

		private void ColorRect_MouseLeave(object sender, MouseEventArgs e)
		{
			((Rectangle)sender).Stroke = Brushes.Transparent;
			((Rectangle)sender).StrokeThickness = 0;
		}

		private void ColorRect_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
		{
			try
			{
				SelectedColor = ((sender as Rectangle).Fill as SolidColorBrush).Color;
			}
			catch { }
		}

		private void Transparent_MouseEnter(object sender, MouseEventArgs e)
		{
			transparentBorder.BorderBrush = Brushes.White;
		}

		private void Transparent_MouseLeave(object sender, MouseEventArgs e)
		{
			transparentBorder.BorderBrush = Brushes.Black;
		}

		private void Transparent_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
		{
			SelectedColor = Colors.Transparent;
		}
	}
}
